import React, {useCallback, useEffect, useMemo, useState} from "react"
import {Pageable} from "../../utils/Page";
import {
    createGoodsBrand, deleteGoodsBrand, disableGoodsBrand, enableGoodsBrand,
    queryGoodsBrands,
    QueryGoodsBrandsResponse,
    updateGoodsBrand
} from "../../apis/GoodsBrandsApi";
import AuthorizationResource from "../../components/AuthorizationResource";
import {Button, ConfigProvider, Form, Input, Select, Space, Table, Tag} from "antd";
import {DeleteOutlined, EditOutlined, PlusOutlined} from "@ant-design/icons";
import {
    buildDisableOrEnableColumnProps,
    castFilterValue,
    mergePaginationAndPageable,
    useTableSearchTextColumnProps
} from "../../utils/AntdTableUtils";
import DataPageLayout from "../../components/DataPageLayout";
import FormDrawer from "../../components/FormDrawer";
import {observerDashboardPageWrapper} from "./ObserverDashboardPageWrapper";
import {getAllGoodsBrandGroup, GoodsBrandGroupSummary} from "../../apis/GoodsBrandGroupApi";
import employeeAuthorizationStore from "../../store/EmployeeAuthorizationStore";
import LoadableButton from "../LoadableButton";
import {NumberIdAndName} from "../../types/BasicModels";
import {createFactory, getAllFactory} from "../../apis/FactoriesApi";
import RefreshableSelectFormItem from "../RefreshableSelectFormItem";
import QuickCreatableSelectFormItem from "../QuickCreatableSelectFormItem";
import {FormInstance} from "antd/es/form/hooks/useForm";
import {createGoodsBrandTag, queryAllGoodsBrandTags} from "../../apis/GoodsBrandTagApi";
import {DisableCondition, disableInConditionToDisableInRequest} from "./GoodsPage";
import {disableGoods, enableGoods} from "../../apis/GoodsApi";

export interface GoodsBrandProps {

}

export interface GoodsBrandFormData {
    name: string
    factoryId?: number
    groupId?: number
    tagIds: number[]
}

const GoodsBrandPage: React.FC<GoodsBrandProps> = () => {
    const [openAddDrawer, setOpenAddDrawer] = useState(false)
    const [pageable, setPageable] = useState(new Pageable())
    const [data, setData] = useState<QueryGoodsBrandsResponse[]>([])
    const [searchNameText, setSearchNameText] = useState<string>()
    const [loading, setLoading] = useState(false)
    const [totalElements, setTotalElements] = useState(0)
    const [disable,setDisable] = useState<DisableCondition>(["0"])
    let query = useCallback(async () => {
        setLoading(true)
        try {
            const response = await queryGoodsBrands({name: searchNameText,disable:disableInConditionToDisableInRequest(disable)}, pageable);
            setTotalElements(response.data.totalElements);
            setData(response.data.content);
        } finally {
            setLoading(false);
        }
    }, [...pageable.toDependencyList(), searchNameText,disable]);

    const [editGoodsId, setEditingItemId] = useState<number>()
    const editingItem = useMemo(() => {
        return data.find(it => it.id === editGoodsId)
    }, [editGoodsId, data]);

    useEffect(() => {
        // noinspection JSIgnoredPromiseFromCall
        query()
    }, [query]);
    let nameSearchProps = useTableSearchTextColumnProps<QueryGoodsBrandsResponse>("name", {
        placeholder: "名称"
    });

    const [groups, setGroups] = useState<GoodsBrandGroupSummary[]>([])

    async function queryGoodsBrandGroups() {
        const response = await getAllGoodsBrandGroup();
        setGroups(response.data);
    }

    useEffect(() => {
        // noinspection JSIgnoredPromiseFromCall
        queryGoodsBrandGroups();
    }, []);
    const [factories, setFactories] = useState<NumberIdAndName[]>([])

    async function queryFactories() {
        const response = await getAllFactory();
        setFactories(response.data);
    }

    useEffect(() => {
        // noinspection JSIgnoredPromiseFromCall
        queryFactories();
    }, []);



    const [goodsBrandTags, setGoodsBrandTags] = useState<NumberIdAndName[]>([])
    useEffect(() => {
        queryAllGoodsBrandTags().then(response => {
            setGoodsBrandTags(response.data)
        })
    }, []);
    let [addForm] = Form.useForm();
    let [editForm] = Form.useForm();

    function buildFormItems(formInstance: FormInstance) {
        return <>
            <Form.Item label={"名称"} name="name" rules={[{required: true}]}>
                <Input/>
            </Form.Item>
            <QuickCreatableSelectFormItem name={"factoryId"} label={"厂商"}
                                          onRefresh={queryFactories}
                                          options={factories.map(it => ({label: it.name, value: it.id,}))}
                                          onCreate={async (name) => {
                                              let id = (await createFactory({name})).data;
                                              factories.push({id, name})
                                              setFactories(Array.from(factories))
                                              formInstance.setFieldValue("factoryId", id)
                                          }}/>

            {/*<RefreshableSelectFormItem label={"分组"} name={"groupId"} onRefresh={queryGoodsBrandGroups} builder={
                refreshing => <Select placeholder={"选择分组"} loading={refreshing}>
                    {groups.map(group => {
                        return <Select.Option key={group.id} value={group.id}>{group.name}</Select.Option>
                    })}
                </Select>
            }/>*/}
            <QuickCreatableSelectFormItem name={"tagIds"} label={"标签"}
                                          mode={"multiple"}
                                          options={goodsBrandTags.map(it => ({label: it.name, value: it.id}))}
                                          onCreate={async (name)=>{
                                              let response  = await createGoodsBrandTag({name})
                                              goodsBrandTags.push({id:response.data,name})
                                              setGoodsBrandTags(Array.from(goodsBrandTags))
                                              let tags = formInstance.getFieldValue("tagIds")??[];
                                              tags.push(response.data)
                                              formInstance.setFieldValue("tagIds",Array.from(tags))
                                          }}/>
        </>
    }

    return <>
        <DataPageLayout rightActions={<AuthorizationResource authorities={["货品_品牌_新增"]}>
            <Button type={"primary"} onClick={() => {
                setOpenAddDrawer(true)
            }}><PlusOutlined/>新增品牌</Button>
        </AuthorizationResource>}>
            <ConfigProvider componentSize={"small"}>
                <Table<QueryGoodsBrandsResponse> loading={loading} dataSource={data} rowKey={"id"} pagination={{
                    current: pageable.page,
                    pageSize: pageable.size,
                    total: totalElements,
                }} onChange={(pagination, filters, sorter) => {
                    setSearchNameText(castFilterValue(filters.name))
                    setPageable(mergePaginationAndPageable(pagination, pageable, sorter))
                    setDisable(filters.disable as any)
                }} columns={[
                    {
                        dataIndex: "name",
                        title: "名称",
                        ...nameSearchProps,
                    },
                    {
                        dataIndex: ["factory", "name"],
                        key: "factory.name",
                        title: "厂商",
                    },
                    /*{
                        dataIndex: ["group", "name"],
                        title: "分组",
                        key: "group.name",
                    },*/
                    {
                        dataIndex: "tags",
                        key: "tags",
                        render: (value: Array<NumberIdAndName>, record, index) => {
                            return <Space>
                                {value.map(it => {
                                    return <Tag key={it.id}>{it.name}</Tag>
                                })}
                            </Space>
                        },
                        title:"标签",
                    },
                    {
                        dataIndex: "goodsAmount",
                        title: "货品数量"
                    },
                    buildDisableOrEnableColumnProps(disable),
                    {
                        title: "操作",
                        render: (_, item) => {
                            return <Space>
                                {employeeAuthorizationStore.hasAuthority("货品_品牌_修改")
                                    && <Button type={"link"}
                                               onClick={() => {
                                                   setEditingItemId(item.id)
                                               }}>
                                        <EditOutlined/>
                                    </Button>
                                }
                                {employeeAuthorizationStore.hasAuthority("货品_品牌_删除")
                                    && !item.goodsAmount
                                    && <LoadableButton type={"link"}
                                                       danger
                                                       onClick={async () => {
                                                           await deleteGoodsBrand(item.id)
                                                           await query()
                                                       }}>
                                        <DeleteOutlined/>
                                    </LoadableButton>
                                }
                                {employeeAuthorizationStore.hasAuthority("货品_品牌_修改") && <LoadableButton
                                    type={"link"}
                                    danger={!item.disable}
                                    onClick={async (event) => {
                                        event.stopPropagation()
                                        item.disable ? await enableGoodsBrand(item.id) : await disableGoodsBrand(item.id)
                                        await query()
                                    }}>{item.disable ? "启用" : "禁用"}</LoadableButton>}
                            </Space>
                        }

                    },

                ]}>
                    <Table.Column dataIndex={"name"} title={"名称"} {...nameSearchProps}/>
                    <Table.Column dataIndex={["factory", "name"]} key={"factory.name"} title={"厂商"}/>
                    <Table.Column dataIndex={"goodsAmount"} title={"商品数量"}/>
                    <Table.Column<QueryGoodsBrandsResponse> title={"操作"} render={(_, item) => {
                        return <Space>
                            {employeeAuthorizationStore.hasAuthority("货品_品牌_修改")
                                && <Button type={"link"}
                                           onClick={() => {
                                               setEditingItemId(item.id)
                                           }}>
                                    <EditOutlined/>
                                </Button>
                            }
                            {employeeAuthorizationStore.hasAuthority("货品_品牌_删除")
                                && !item.goodsAmount
                                && <LoadableButton type={"link"}
                                                   danger
                                                   onClick={async () => {
                                                       await deleteGoodsBrand(item.id)
                                                       await query()
                                                   }}>
                                    <DeleteOutlined/>
                                </LoadableButton>
                            }
                        </Space>
                    }}/>
                </Table>
            </ConfigProvider>
        </DataPageLayout>
        <FormDrawer<GoodsBrandFormData> form={addForm} onClose={() => setOpenAddDrawer(false)}
                                        title={"新增品牌"}
                                        onConfirm={async (values) => {
                                            return createGoodsBrand(values).then(() => {
                                                setOpenAddDrawer(false)
                                                query()
                                            })
                                        }}
                                        open={openAddDrawer}>
            {buildFormItems(addForm)}
        </FormDrawer>
        <FormDrawer<GoodsBrandFormData> open={!!editingItem} title={"修改品牌"} onClose={() => {
            setEditingItemId(undefined)
        }} onConfirm={async (values) => {
            return updateGoodsBrand(editGoodsId!!, values).then(() => {
                query()
                setEditingItemId(undefined)
            })
        }} initialValues={{
            name: editingItem?.name ?? "",
            factoryId: editingItem?.factory?.id,
            groupId: editingItem?.group?.id,
            tagIds: editingItem?.tags?.map(it => it.id) ?? [],
        }}>
            {buildFormItems(editForm)}
        </FormDrawer>
    </>
}

export default observerDashboardPageWrapper(GoodsBrandPage, "goods/brands", "货品品牌")